package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njworkorder.Entity.AdministrativeOrganization;
import com.njworkorder.Entity.Route;
import com.njworkorder.Entity.Section;
import com.njworkorder.Entity.Stake;
import com.njworkorder.Service.AdministrativeOrganizationService;
import com.njworkorder.Service.RouteService;
import com.njworkorder.Service.SectionService;
import com.njworkorder.Service.StakeService;
import com.njworkorder.Utils.LonLatUtil;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.LngLat;
import com.njworkorder.VO.SectionRouteVo;
import com.njworkorder.VO.StakeVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;


@Tag(name = "桩号管理",description = "桩号经纬度信息管理")
@RestController
@RequestMapping("/stake")
public class StakeController {

    private final StakeService stakeService;
    private final RouteService routeService;
    private final SectionService sectionService;
    private final AdministrativeOrganizationService organizationService;
    public StakeController(StakeService stakeService,RouteService routeService,SectionService sectionService,
                           AdministrativeOrganizationService organizationService) {
        this.stakeService = stakeService;
        this.routeService = routeService;
        this.sectionService = sectionService;
        this.organizationService = organizationService;
    }


    @Operation(summary = "根据路段编号查询桩号")
    @GetMapping("/getRouteList")
    public Result<Page<Stake>> getDicListTree(@RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize, @RequestParam(value = "RouteNo",required = false) String RouteNo) {

        LambdaQueryWrapper<Stake> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply("1=1")
                .eq(RouteNo!=null &&!RouteNo.isEmpty(), Stake::getRouteNo,RouteNo);
        Page<Stake> page = new Page<>(pageIndex, pageSize);
        Page<Stake> page1 = stakeService.page(page, queryWrapper);
        return ResultUtil.success(page1);
    }


    @Operation(summary = "根据路线编号获取对应所有桩号经纬度")
    @GetMapping("/getRouteLogLatInfos")
    public Result<List<Map<String,Object>>> getRouteLogLatInfos(@Schema(description = "路线编号")
                                                         @RequestParam(value = "routeNo",required = false) String routeNo){
        LambdaQueryWrapper<Route> wrapperR = new LambdaQueryWrapper<Route>()
                .select(Route::getId,Route::getRouteNo,Route::getRouteName,Route::getCompanyNo,
                        Route::getStartStake,Route::getEndStake,Route::getMainLineMileage,Route::getTotalMileage)
                .eq(StringUtils.isNotEmpty(routeNo),Route::getRouteNo,routeNo)
                .apply("1=1");
        List<Route> listRoute = routeService.list(wrapperR);

        MPJLambdaWrapper<Section> lambdaWrapper = new MPJLambdaWrapper<Section>()
                .selectAs(Section::getId,SectionRouteVo::getId)
                .selectAs(Section::getRouteId,SectionRouteVo::getRouteId)
                .selectAs(Section::getWorkspaceId,SectionRouteVo::getWorkspaceId)
                .selectAs(Route::getCompanyNo,SectionRouteVo::getCompanyNo)
                .selectAs(Route::getRouteNo,SectionRouteVo::getRouteNo)
                .leftJoin(Route.class,Route::getId,Section::getRouteId)
                .apply("1=1");
        List<SectionRouteVo> sectionRouteVos = sectionService.selectJoinList(SectionRouteVo.class, lambdaWrapper);

        MPJLambdaWrapper<Stake> wrapper = new MPJLambdaWrapper<Stake>()
                .selectAs(Stake::getRouteNo,LngLat::getRouteNo)
                .selectAs(Stake::getGcjLng, LngLat::getLng)
                .selectAs(Stake::getGcjLat,LngLat::getLat)
                .eq(StringUtils.isNotEmpty(routeNo),Stake::getRouteNo,Route::getRouteNo)
                .apply("1=1");
        List<LngLat> stakeVos = stakeService.selectJoinList(LngLat.class, wrapper);

        Map<String, List<LngLat>> collect = stakeVos.stream().collect(Collectors.groupingBy(LngLat::getRouteNo));

        List<StakeVo> stakeVoList = new ArrayList<>();
        collect.forEach((key, value) ->
        {
            StakeVo stakeVo = new StakeVo();
            stakeVo.setRouteNo(key);
            List<Route> list = listRoute.stream().filter(f -> f.getRouteNo().equals(key)).toList();
            if(!list.isEmpty()){

                long count = sectionRouteVos.stream().filter(f -> f.getRouteId().equals(list.getFirst().getId())).count();
                stakeVo.setWorkspaceCount((int)count);
                stakeVo.setRouteName(list.getFirst().getRouteName());
                stakeVo.setStartStake(list.getFirst().getStartStake());
                stakeVo.setEndStake(list.getFirst().getEndStake());
                stakeVo.setMainLineMileage(list.getFirst().getMainLineMileage());
                stakeVo.setTotalMileage(list.getFirst().getTotalMileage());
            }
            if(key.equals("JSJKLX003001")){
                stakeVo.setLngLats(value.stream().sorted(Comparator.comparing(LngLat::getLat)).toList());
            }else{
                stakeVo.setLngLats(value);
            }
            stakeVoList.add(stakeVo);
        });


        List<String> list = listRoute.stream().map(Route::getCompanyNo).distinct().toList();
        LambdaQueryWrapper<AdministrativeOrganization> wrapper1 = new LambdaQueryWrapper<AdministrativeOrganization>()
                .in(AdministrativeOrganization::getId, list);
        List<AdministrativeOrganization> list1 = organizationService.list(wrapper1);


        List<Map<String,Object>> mapList = new ArrayList<>();
        Map<String,Object> map;
        for (AdministrativeOrganization item : list1){
            List<String> list2 = sectionRouteVos.stream().filter(f -> f.getCompanyNo().equals(item.getId())).map(SectionRouteVo::getRouteNo).toList();
            Set<String> targetIds = new HashSet<>(list2);

            List<StakeVo> list3 = stakeVoList.stream().filter(f ->  targetIds.contains(String.valueOf(f.getRouteNo()))).toList();

            map = new HashMap<>();
            map.put("companyName",item.getName());
            map.put("workspaceCount",sectionRouteVos.stream().filter(f -> f.getCompanyNo().equals(item.getId())).collect(Collectors.groupingBy(SectionRouteVo::getWorkspaceId)).size());
            map.put("stakeVoList",list3);
            mapList.add(map);
        }

        return ResultUtil.success(mapList);
    }


    @Operation(summary = "维护坐标信息WGS84转GCJ02")
    @GetMapping("/maintenanceCoordinate")
    public Result<String> maintenanceCoordinate(@RequestParam("password") String password){

        if(password.equals("654321")){
            LambdaQueryWrapper<Stake> wrapper = new LambdaQueryWrapper<Stake>()
                    .select(Stake::getId,Stake::getLng,Stake::getLat)
                    .apply("1=1");
            List<Stake> list = stakeService.list(wrapper);

            for (Stake stake : list) {
                double[] doubles = LonLatUtil.wgs84ToGcj02(Double.parseDouble(stake.getLat()), Double.parseDouble(stake.getLng()));
                LambdaUpdateWrapper<Stake> updateWrapper = new LambdaUpdateWrapper<Stake>()
                        .set(Stake::getGcjLat,doubles[0])
                        .set(Stake::getGcjLng,doubles[1])
                        .eq(Stake::getId,stake.getId());
                stakeService.update(updateWrapper);
            }
            return ResultUtil.success("维护完毕！");
        }
        return ResultUtil.success("密码输入错误！接口不执行！");
    }


}
